#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("TCP服务端");
    //连接信号槽 （ 当有客户端连接的时候发出newConnection信号）
    connect(&m_tcpServer,  SIGNAL(newConnection()),
            this , SLOT(onNewConnection()));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_btnStart_clicked()
{
    if(!m_start)
    {
        QString ip = ui->lineEditIP->text();
        uint port  = ui->lineEditPort->text().toUInt();
        bool  ret= m_tcpServer.listen(QHostAddress(ip), port);
        if(ret)
        {
            ui->messageShoxEdit->appendPlainText("服务器启动成功！");
            ui->btnStart->setText("停止");
            m_start = true;
        }
        else
        {
            ui->messageShoxEdit->appendPlainText("服务器启动失败！");
        }
    }
    else
    {
        //关闭与所有客户端的连接
        std::for_each(m_clientList.begin(),m_clientList.end(),[](QTcpSocket* c){
            c->close();
        });
        //关闭TCP的监听
        m_tcpServer.close();
        ui->messageShoxEdit->appendPlainText("服务器已停止!");
        ui->btnStart->setText("启动");
        m_start = false;
    }
}


void Widget::onNewConnection()
{
    //获取该连接与客户端通讯的套接字对象
    QTcpSocket * clientSocket =  m_tcpServer.nextPendingConnection();

    if(clientSocket)
    {
        QString  str= QString("客户端%1:%2连接成功!")
                          .arg(clientSocket->peerAddress().toString())
                          .arg(clientSocket->peerPort());
        ui->messageShoxEdit->appendPlainText(str);

        //接收到数据时发出的信号
        connect( clientSocket, SIGNAL(readyRead()) ,  this , SLOT(onReadyRead()));
        //绑定客户相应套接字的信号
        connect( clientSocket, SIGNAL(disconnected()) , this , SLOT(onDisconnected()));
        //保存到客户端列表
        m_clientList.push_back(clientSocket);
    }
}


void Widget::onReadyRead()
{
    //有数据可以读,但是不知道是哪个客户端发来的数据
    //所以需要遍历每个客户端

//    std::for_each(m_clientList.begin(),m_clientList.end(),[this](QTcpSocket* c){
        QTcpSocket* c = static_cast<QTcpSocket*>(sender());
        QByteArray  data = c->readAll();
            //接收的数据大小
        if(data.size()>0)
        {
            QString msg = data;
            QString  str= QString("收到了%1:%2消息:%3")
                              .arg( c->peerAddress().toString())
                              .arg( c->peerPort())
                              .arg( msg);

            ui->messageShoxEdit->appendPlainText(str);
        }
//    });

}

//客户端断开的时候发送disconnected的信号的槽函数
void   Widget::onDisconnected()
{
    //sender表示发送信号的对象
    QTcpSocket * client = ( QTcpSocket * )sender();

    QString  str= QString("客户端%1:%2断开了！")
                      .arg( client->peerAddress().toString())
                      .arg( client->peerPort()) ;

    ui->messageShoxEdit->appendPlainText(str);

    //从客户端列表移除
    m_clientList.remove(client);

    //关闭QTcpSocket对象
    client->close();

}

void Widget::on_btnSend_clicked()
{
    //获取要发送的内容
    QString  msg = ui->messageEdit->text();
    QByteArray  data = msg.toUtf8();//转换为utf8字节数组
   //群发消息
    foreach( QTcpSocket * c , m_clientList)
    {
        //发送数据
        c->write(data);
    }
}
